本文同步更新於blog
情境:以下是某自助餐餐廳的情況
<?php
namespace App\FacadePattern\Buffet;
class IceCreamMachine
{
    public function addIngredients()
    {
        //倒入牛奶、糖、鮮奶油、蛋黃等
        return $this;
    }
    public function stir()
    {
        //攪拌均勻
        return $this;
    }
    public function chill()
    {
        //使其冷藏
        return $this;
    }
    public function squeeze()
    {
        //擠出霜淇淋
        return '霜淇淋';
    }
}
<?php
namespace App\FacadePattern\Buffet;
class CoffeeMachine
{
    public function addCoffeeBeans()
    {
        //放入咖啡豆
        return $this;
    }
    public function grind()
    {
        //研磨咖啡豆
        return $this;
    }
    public function brew()
    {
        //沖煮咖啡
        return $this;
    }
    public function stirWithMilk()
    {
        //與牛奶攪拌
        return '拿鐵';
    }
}
老闆認為目前的方式,客人必須知道霜淇淋機與咖啡機所有的操作流程。
不是那麼地友好,希望我們能寫個簡單的介面,讓客人更容易取得餐點。
需求一:替霜淇淋機與咖啡機設計簡單的介面,方便取用
<?php
namespace App\FacadePattern\Buffet\Facade;
use App\FacadePattern\Buffet\IceCreamMachine;
class IceCreamMachineFacade
{
    public static function makeIceCream()
    {
        $iceCreamMachine = new IceCreamMachine();
        return $iceCreamMachine
            ->addIngredients()
            ->stir()
            ->chill()
            ->squeeze();
    }
}
<?php
namespace App\FacadePattern\Buffet\Facade;
use App\FacadePattern\Buffet\CoffeeMachine;
class CoffeeMachineFacade
{
    public static function makeLatte()
    {
        $coffeeMachine = new CoffeeMachine();
        return $coffeeMachine
            ->addCoffeeBeans()
            ->grind()
            ->brew()
            ->stirWithMilk();
    }
}
<?php
namespace App\FacadePattern\Buffet;
use App\FacadePattern\Buffet\Facade\CoffeeMachineFacade;
use App\FacadePattern\Buffet\Facade\IceCreamMachineFacade;
class Program
{
    public function makeIceCream()
    {
        return IceCreamMachineFacade::makeIceCream();
    }
    public function makeLatte()
    {
        return CoffeeMachineFacade::makeLatte();
    }
}
這下子,客人終於不用知道太多,便能取得自己想要的餐點了。
[單一職責原則]
我們將子類別與接口類別視作兩種不同的職責。
[開放封閉原則]
對於客戶端與接口類別來說,並不會因為我們用了新的咖啡機而有所區別。
然而當子類別改動時可能會連帶修改到接口類別。
最後附上類別圖:
(註:若不熟悉 UML 類別圖,可參考UML類別圖說明。)
ʕ •ᴥ•ʔ:在這個例子中,我會覺得是霜淇淋機/咖啡機不對,
竟然沒有提供簡單的介面!